package com.phychips;

import com.phychips.rcp.RcpConst;
import com.phychips.rcp.RcpException;

/**
 * JniClass defines the functions to read/write the comport. It is linked to the
 * JNI library (rcp_jni.so).
 *
 * @author jeje0247
 */
public class JniClass {
    static private native int serialOpen(byte[] array, int length);

    static private native void serialClose();

    static private native int serialRead();

    static private native int serialWrite(int data);

    static private native void jniTest();

    static {
        System.loadLibrary("rcp_jni");
    }

    /**
     * This opens the comport
     *
     * @param comport : the comport path
     * @return 0 on success
     * @throws RcpException
     */
    public static int open(String comport) throws RcpException {
        byte[] array;
        int result;

        if (comport.length() > 0) {
            array = comport.getBytes();
            result = serialOpen(array, array.length);

            if (result < 0) {
                if (result == -1) {
                    RcpException exception = new RcpException(
                            "serial open: file open fail",
                            RcpConst.SERIAL_OPEN_FAIL);
                    throw exception;
                } else if (result == -2) {
                    RcpException exception = new RcpException(
                            "serial open: term flush fail",
                            RcpConst.SERIAL_OPEN_FAIL);
                    throw exception;
                } else if (result == -3) {
                    RcpException exception = new RcpException(
                            "serial open: set term fail",
                            RcpConst.SERIAL_OPEN_FAIL);
                    throw exception;
                } else {
                    RcpException exception = new RcpException(
                            "serial open: unknown fail",
                            RcpConst.SERIAL_OPEN_FAIL);
                    throw exception;
                }
            }
            return result;
        } else {
            RcpException exception = new RcpException("invalid com port",
                    RcpConst.INVALID_ARGUMENT);
            throw exception;
        }
    }

    /**
     * This closes the comport.
     */
    public static void close() {
        serialClose();
    }

    /**
     * This reads one character from the comport.
     *
     * @return the character read on success
     * @throws RcpException
     */
    public static int read() throws RcpException {
        int res;
        res = serialRead();

        if (res < 0) {
            RcpException exception = new RcpException("serial read fail",
                    RcpConst.SERIAL_READ_FAIL);
            throw exception;
        }

        return res;
    }

    /**
     * This writes one character to the comport.
     *
     * @param data : character to write
     * @return 0 on success
     * @throws RcpException
     */
    public static int write(int data) throws RcpException {
        int res;

        res = serialWrite(data);

        if (res < 0) {
            RcpException exception = new RcpException("serial write fail",
                    RcpConst.SERIAL_WRITE_FAIL);
            throw exception;
        }

        return res;
    }
}
